import Cesium from '../Ces/Cesium'
import Util from '../Core/Util'
import WeGeometryUtil from '../Display/WeGeometryUtil'
import WeUniform from "../Display/WeUniform"

class FluidParameter {
  private refVertexArray
  private attributeLocations
  private _tmp: any//Cesium.Texture
  private _oceanNormalMap:any// Cesium.Texture
  private _oceanNormalMapUrl: string
  private _oceanNormalMapDirty: boolean = true
  weUniform: WeUniform
  constructor() {
    const floatUniform = {
      height: 0,
      rain: 0.005,
      evaporate: 0.05,
      speedFactor: 1.2,
      maxWaterHeight: 200,
      normalFactor: 1,
    }

    const vec3Uniform = {
      deepColor: new Cesium.Cartesian3(0.0, 51.0 / 255.0 * 0.4, 128.0 / 255.0 * 0.4),
      turbulentColor: new Cesium.Cartesian3(55.0 / 255.0 * 0.7, 212.0 / 255.0 * 0.7, 1.0 * 0.7),
    }

    const vec4Uniform = {
      rainCircle1: new Cesium.Cartesian4(0.0, 0.0, 0.0, 0.0),
      rainCircle2: new Cesium.Cartesian4(0.0, 0.0, 0.0, 0.0),
      rainCircle3: new Cesium.Cartesian4(0.0, 0.0, 0.0, 0.0),
      rainCircle4: new Cesium.Cartesian4(0.0, 0.0, 0.0, 0.0),
      rainCircle5: new Cesium.Cartesian4(0.0, 0.0, 0.0, 0.0),
    }
    this.weUniform = new WeUniform({
      floatUniform,
      vec3Uniform,
      vec4Uniform,
      name: 'FluidParameter_Uniform'
    })
  }

  set deepColor(value) {
    this.weUniform.Properties.deepColor = value
  }
  set turbulentColor(value) {
    this.weUniform.Properties.turbulentColor = value
  }

  set normalFactor(value) {
    this.weUniform.Properties.normalFactor = value
  }

  set maxWaterHeight(value) {
    this.weUniform.Properties.maxWaterHeight = value
  }

  set speedFactor(value) {
    this.weUniform.Properties.speedFactor = value
  }

  set rain(value) {
    this.weUniform.Properties.rain = value
  }

  set evaporate(value) {
    this.weUniform.Properties.evaporate = value
  }

  set height(value) {
    this.weUniform.Properties.height = value
  }

  set rainCircle1(value) {
    this.weUniform.Properties.rainCircle1 = value
  }

  set rainCircle2(value) {
    this.weUniform.Properties.rainCircle2 = value
  }

  set rainCircle3(value) {
    this.weUniform.Properties.rainCircle3 = value
  }

  set rainCircle4(value) {
    this.weUniform.Properties.rainCircle4 = value
  }

  set rainCircle5(value) {
    this.weUniform.Properties.rainCircle5 = value
  }

  getSource() {
    return this.weUniform.getSource(true)
  }

  setupUniformMap(uniformMap) {
    this.weUniform.setupUniformMap(uniformMap)
  }

  getVertexArray(context, width, height) {
    if (!this.refVertexArray) {
      const { vertexArray, attributeLocations } = WeGeometryUtil.createCubeGeometry(
        context, width, height, 2
      )
      this.refVertexArray = vertexArray
      this.attributeLocations = attributeLocations
      Util.setRefDestroy(vertexArray, 0, () => {
        this.refVertexArray = undefined
        this.attributeLocations = undefined
      })
    }
    this.refVertexArray.refCount++
    return {
      vertexArray: this.refVertexArray,
      attributeLocations: this.attributeLocations,
    }
  }

  set oceanNormalMapUrl(value) {
    this._oceanNormalMapUrl = value
    this._oceanNormalMapDirty = true
  }

  getTempTex(context, width, height) {
    if (!this._tmp) {
      this._tmp = new Cesium.Texture({
        context,
        pixelFormat: Cesium.PixelFormat.RGBA,
        pixelDatatype: Cesium.PixelDatatype.FLOAT,
        width: width,
        height: height,
        sampler: new Cesium.Sampler({
          minificationFilter: Cesium.TextureMinificationFilter.NEAREST,
          magnificationFilter: Cesium.TextureMagnificationFilter.NEAREST,
        })
      })
    }
    return this._tmp
  }

  getNormalTex(context) {
    if (!this._oceanNormalMap && this._oceanNormalMapDirty) {
      this._oceanNormalMapDirty = false
      const url = this._oceanNormalMapUrl ||
        Cesium.buildModuleUrl("Assets/Textures/waterNormalsSmall.jpg")
      const that = this
      Cesium.Resource.fetchImage(url).then(function (image) {
        that._oceanNormalMap =
          that._oceanNormalMap && that._oceanNormalMap.destroy();
        that._oceanNormalMap = new Cesium.Texture({
          context,
          source: image,
          sampler: new Cesium.Sampler({
            wrapS: Cesium.TextureWrap.REPEAT,
            wrapT: Cesium.TextureWrap.REPEAT,
          })
        })
      })
    }
    return this._oceanNormalMap || context.defaultTexture
  }


  destroy() {
    this._tmp = this._tmp && this._tmp.destroy()
    this._oceanNormalMap = this._oceanNormalMap && this._oceanNormalMap.destroy()
    return Cesium.destroyObject(this)
  }
  isDestroyed() {
    return false
  }
}

export default FluidParameter
